package com.example.demo.service.My.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.ErrorCode;
import com.example.demo.exception.BusinessException;
import com.example.demo.mapper.TeacherMapper;
import com.example.demo.myModel.entity.Email;
import com.example.demo.myModel.entity.Teacher;
import com.example.demo.myModel.otd.user.AdminLoginRequest;
import com.example.demo.myModel.vo.AdminLoginVo;
import com.example.demo.service.My.TeacherService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import java.lang.reflect.Field;
import java.util.Random;

import static com.example.demo.constant.UserConstant.USER_LOGIN_STATE;

@Component
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {
    @Autowired
    private JavaMailSenderImpl mailSender;

    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "example.demo";

    // application.properties配置的值
    @Value("${spring.mail.username}")
    private String from;


    /**
     * 获取已经登录的管理员脱敏信息
     * @param teacher 管理员信息
     * @return {AdminLoginVo}
     */
    @Override
    public AdminLoginVo getLoginAdminVO(Teacher teacher) {
        if (teacher == null) {
            return null;
        }
        AdminLoginVo loginAdminVO = new AdminLoginVo();
        BeanUtils.copyProperties(teacher, loginAdminVO);
        return loginAdminVO;
    }


    /**
     * 管理员注册
     * @param teacher 请求类
     * @param session 缓存状态
     * @return
     * {
     *     long
     * }
     */
    @Override
    public Long adminRegister(Teacher teacher, HttpSession session) {
        // 1. 校验
        if (StringUtils.isAnyBlank(teacher.getTeacherId().toString(), teacher.getPassword(), teacher.getTeacherName())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (teacher.getPassword().length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
        }
        if (teacher.getTeacherId().toString().length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
        }
        if (!registered(teacher,session)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误，请重新输入");
        }
        synchronized (teacher.getTeacherId().toString().intern()) {
            // 账户不能重复
            QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("teacherId", teacher.getTeacherId());
            long count = this.baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
            }
            // 2. 加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + teacher.getPassword()).getBytes());
            // 3. 插入数据
            Teacher teacher1 = new Teacher();
            teacher1=teacher;
            teacher1.setPassword(encryptPassword);
            teacher1.setID(Long.parseLong(randomCode(8)));
            boolean saveResult = this.save(teacher1);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
            }
            return teacher1.getID();
        }
    }



    /**
     * 管理员登录
     * @param adminLoginRequest 请求实体
     * @param request 请求信息
     * @return
     */
    @Override
    public AdminLoginVo adminLogin(AdminLoginRequest adminLoginRequest, HttpServletRequest request) {
        // 1. 校验
        if (adminLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (adminLoginRequest.getTeacherId().toString().length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
        }
        if (adminLoginRequest.getPassword().length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + adminLoginRequest.getPassword()).getBytes());
        // 查询用户是否存在
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacherId", adminLoginRequest.getTeacherId());
        queryWrapper.eq("password", encryptPassword);
        System.out.println(queryWrapper.getSqlSelect());
        Teacher teacher = this.baseMapper.selectOne(queryWrapper);
        // 用户不存在
        if (teacher == null) {
            //log.info("user login failed, userAccount cannot match userPassword");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
        }
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, teacher);
        return this.getLoginAdminVO(teacher);
    }



    /**
     * 发送邮箱验证码
     * @param email
     * @param session
     * @return
     */
    @Override
    public boolean sentEmailCode(Email email, HttpSession session ) {
        try {
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
            // 生成随机数
            String code = randomCode(6);

            // 将随机数放置到session中
            session.setAttribute("email", email.getEmail());
            session.setAttribute("code", code);
            session.setAttribute("teacherId",email.getUserId());

            simpleMailMessage.setSubject("验证码邮件"); // 主题
            simpleMailMessage.setText("您收到的验证码是："+code); // 内容
            simpleMailMessage.setFrom(from); // 发件人
            simpleMailMessage.setTo(email.getEmail()); // 收件人
            mailSender.send(simpleMailMessage); // 发送
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "发送失败");
        }
    }

    /**
     * 随机生成6位数的验证码
     * @return String code
     */
    @Override
    public String randomCode(int n) {
        StringBuilder str = new StringBuilder();
        Random random = new Random();
        for(int i = 0;i < n; i++) {
            str.append(random.nextInt(10));
        }
        return str.toString();
    }



    /**
     * 检验验证码
     * @param info
     * @param session
     * @return
     */
    @Override
    public boolean registered(Teacher info, HttpSession session) {
        // 获取session中的验证信息
        String email = (String) session.getAttribute("email");
        String code = (String) session.getAttribute("code");
        long userId=(long)session.getAttribute("userId");
        // 获取表单中的提交的验证信息
        String voCode =  info.getCode();
        //如果emial数据为空或者不一致都失败
        if(email == null || email.isEmpty()) {
            //return "error,请重新注册";
            return false;
        }else if (!code.equals(voCode)||userId!=info.getTeacherId()){
            //return "error,请重新注册";
            return false;
        }
        // 跳转成功页面
        return true;
    }
}
